-- 测试环境
-- package.path = package.path .. ";?.lua"
-- 生产环境
package.path = "./plugin/B10440/utils.lua" .. ";..\\?.lua"

require("utils")
require("json")

-- 判断测试环境
function TestEnv() -- true:测试环境  false:生产环境
    return string.find(package.path, "utils") == nil and true or false
end

rxBuf = TestEnv() == true and
    { 0xFE, 0xFE, 0xFE, 0xFE, 0x68, 0x02, 0x80, 0x01, 0x09, 0x21, 0x20, 0x68, 0x91,
        0x17, 0x34, 0x38, 0x32, 0x37, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
        0x34, 0x34, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xE5, 0x16 } or {}

-- 仅在测试环境下的打印
function Luaprint(str) --
    if (TestEnv() == true) then
        print(str)
    end
end

regAddr = 0x0000
function PrintTable(tab)
    local message = ""
    for i = 1, #tab do
        message = message .. string.format("%02X", tab[i]) .. " "
    end
    Luaprint("requestADU:" .. message)
end

-- 解析sAddr对应的空调内外机地址
function AnalysisAddr(Addr) --
    local tabAddr = {}
    for i = 1, 6 do
        tabAddr[i] = tonumber(string.sub(Addr, 2 * i - 1, 2 * i), 16)
    end
    tabAddr = ReverseTable(tabAddr, false)
    return tabAddr
end

function GenerateGetRealVariables(sAddr, step)
    local requestADU = {}
    local VariableMap = {
        Status = "0",
        Variable = {}
    }
    local addr = AnalysisAddr(sAddr)
    if (step == 0) then -- 电量参数
        requestADU[1] = 0x68 -- 帧起始符68H
        requestADU[2] = addr[1] -- 地址域A0
        requestADU[3] = addr[2] -- 地址域A1
        requestADU[4] = addr[3] -- 地址域A2
        requestADU[5] = addr[4] -- 地址域A3
        requestADU[6] = addr[5] -- 地址域A4
        requestADU[7] = addr[6] -- 地址域A5
        requestADU[8] = 0x68 -- 帧起始符68H
        requestADU[9] = 0x11 -- 控制码
        requestADU[10] = 0x04 -- 数据域长度
        requestADU[11] = 0x35 -- 标识码
        requestADU[12] = 0x3B -- 标识码
        requestADU[13] = 0x32 -- 标识码
        requestADU[14] = 0x37 -- 标识码
        local crc = GetCRC(requestADU, 1)
        if (crc == nil) then
            VariableMap = {
                Status = "1",
                Variable = {}
            }
            return VariableMap
        end
        requestADU[15] = crc -- 校验码
        requestADU[16] = 0x16 -- 结束符

        VariableMap = {
            Status = "1",
            Variable = requestADU
        }
    elseif (step == 1) then -- 故障分析、事件分析
        requestADU[1] = 0x68 -- 帧起始符68H
        requestADU[2] = addr[1] -- 地址域A0
        requestADU[3] = addr[2] -- 地址域A1
        requestADU[4] = addr[3] -- 地址域A2
        requestADU[5] = addr[4] -- 地址域A3
        requestADU[6] = addr[5] -- 地址域A4
        requestADU[7] = addr[6] -- 地址域A5
        requestADU[8] = 0x68 -- 帧起始符68H
        requestADU[9] = 0x11 -- 控制码
        requestADU[10] = 0x04 -- 数据域长度
        requestADU[11] = 0x34 -- 标识码
        requestADU[12] = 0x38 -- 标识码
        requestADU[13] = 0x32 -- 标识码
        requestADU[14] = 0x37 -- 标识码
        local crc = GetCRC(requestADU, 1)
        if (crc == nil) then
            VariableMap = {
                Status = "1",
                Variable = {}
            }
            return VariableMap
        end
        requestADU[15] = crc -- 校验码
        requestADU[16] = 0x16 -- 结束符

        VariableMap = {
            Status = "0",
            Variable = requestADU
        }
    end
    PrintTable(requestADU)
    return VariableMap
end

function DeviceCustomCmd(sAddr, cmdName, cmdParam, step)
    local requestADU = {}
    local VariableMap = {
        Status = "0",
        Variable = {}
    }
    local addr = AnalysisAddr(sAddr)
    if (cmdName == "GetRealVariables") then

        if (step == 0) then -- 电量参数
            requestADU[1] = 0x68 -- 帧起始符68H
            requestADU[2] = addr[1] -- 地址域A0
            requestADU[3] = addr[2] -- 地址域A1
            requestADU[4] = addr[3] -- 地址域A2
            requestADU[5] = addr[4] -- 地址域A3
            requestADU[6] = addr[5] -- 地址域A4
            requestADU[7] = addr[6] -- 地址域A5
            requestADU[8] = 0x68 -- 帧起始符68H
            requestADU[9] = 0x11 -- 控制码
            requestADU[10] = 0x04 -- 数据域长度
            requestADU[11] = 0x35 -- 数据域
            requestADU[12] = 0x3B -- 数据域
            requestADU[13] = 0x32 -- 数据域
            requestADU[14] = 0x37 -- 数据域
            local crc = GetCRC(requestADU, 1)
            if (crc == nil) then
                VariableMap = {
                    Status = "1",
                    Variable = {}
                }
                return VariableMap
            end
            requestADU[15] = crc -- 校验码
            requestADU[16] = 0x16 -- 结束符

            VariableMap = {
                Status = "1",
                Variable = requestADU
            }
        elseif (step == 1) then -- 故障分析、事件分析
            requestADU[1] = 0x68 -- 帧起始符68H
            requestADU[2] = addr[1] -- 地址域A0
            requestADU[3] = addr[2] -- 地址域A1
            requestADU[4] = addr[3] -- 地址域A2
            requestADU[5] = addr[4] -- 地址域A3
            requestADU[6] = addr[5] -- 地址域A4
            requestADU[7] = addr[6] -- 地址域A5
            requestADU[8] = 0x68 -- 帧起始符68H
            requestADU[9] = 0x11 -- 控制码
            requestADU[10] = 0x04 -- 数据域长度
            requestADU[11] = 0x34 -- 数据域
            requestADU[12] = 0x38 -- 数据域
            requestADU[13] = 0x32 -- 数据域
            requestADU[14] = 0x37 -- 数据域
            local crc = GetCRC(requestADU, 1)
            if (crc == nil) then
                VariableMap = {
                    Status = "1",
                    Variable = {}
                }
                return VariableMap
            end
            requestADU[15] = crc -- 校验码
            requestADU[16] = 0x16 -- 结束符

            VariableMap = {
                Status = "0",
                Variable = requestADU
            }
        end
    elseif (cmdName == "SetVariables") then
        local ManualOnOff = 0
        res = json.jsondecode(cmdParam)
        if (res["StartStopStatus"] == nil) then
            VariableMap = {
                Status = "1",
                Variable = {}
            }
            return VariableMap
        end
        ManualOnOff = tonumber(res["StartStopStatus"])
        local time = os.date("*t", os.time() + 10)
        requestADU[1] = 0x68 -- 帧起始符68H
        requestADU[2] = addr[1] -- 地址域A0
        requestADU[3] = addr[2] -- 地址域A1
        requestADU[4] = addr[3] -- 地址域A2
        requestADU[5] = addr[4] -- 地址域A3
        requestADU[6] = addr[5] -- 地址域A4
        requestADU[7] = addr[6] -- 地址域A5
        requestADU[8] = 0x68 -- 帧起始符68H
        requestADU[9] = 0x1C -- 控制码
        requestADU[10] = 0x10 -- 数据域长度
        requestADU[11] = 0x35 -- 密级PA
        requestADU[12] = 0x43 -- 密码P0
        requestADU[13] = 0x43 -- 密码P1
        requestADU[14] = 0x43 -- 密码O2e
        requestADU[15] = 0x44 -- 操作者代码C0
        requestADU[16] = 0x44 -- 操作者代码C1
        requestADU[17] = 0x44 -- 操作者代码C2
        requestADU[18] = 0x44 -- 操作者代码C3
        requestADU[19] = ManualOnOff == 0 and 0x4D or 0x4E -- 命令N1
        requestADU[20] = 0x33 -- 保留字节N2
        requestADU[21] = tonumber(time["sec"]) -- 有效截止时间N3
        requestADU[22] = time["min"] -- 有效截止时间N4
        requestADU[23] = time["hour"] -- 有效截止时间N5
        requestADU[24] = time["day"] -- 有效截止时间N6
        requestADU[25] = time["month"] -- 有效截止时间N7
        requestADU[26] = math.modf(time["year"] % 256) -- 有效截止时间N8
        local crc = GetCRC(requestADU, 1)
        if (crc == nil) then
            VariableMap = {
                Status = "1",
                Variable = {}
            }
            return VariableMap
        end
        requestADU[27] = crc -- 校验码
        requestADU[28] = 0x16 -- 停止位

        VariableMap = {
            Status = "0",
            Variable = requestADU
        }
    end
    PrintTable(requestADU)
    return VariableMap
end

-- 获取校验码
function GetCRC(t, startIndex) --
    local sum = 0
    if (type(t) == "table") then
        local len = #t
        for i = startIndex, len do
            sum = sum + t[i]
        end

        if (sum > 0xff) then -- 取低八位
            sum = math.modf(sum % 256) -- s & 0xff
        end
    end
    return sum
end

-- 解析接收的数据
function AnalysisRxData(tabRxbuf, tabBytes, index, bOffset) -- 目标table | 字节数table | 起始索引 | 结果是否减去0x33
    local tabRes = {}
    local strRes = {}

    for i = 1, #tabBytes do
        local tmp = {}
        for k = 1, tabBytes[i] do
            tmp[k] = tabRxbuf[index]
            index = index + 1
        end
        tabRes[i], strRes[i] = ReverseTable(tmp, bOffset)
    end
    return strRes, tabRes
end

-- table取反(1234变为4321)
function ReverseTable(tab, bOffset) -- 目标table | 结果是否减去0x33
    local resTable = {}
    local str = ""
    for i = 1, #tab do
        resTable[i] = tab[#tab + 1 - i] - (bOffset == true and 0x33 or 0)
        if (resTable[i] < 0) then
            resTable[i] = 256 + resTable[i]
        end
        str = str .. string.format("%02X", resTable[i])
    end
    return resTable, str
end

-- 求以2为底n的对数
function lg2(n)
    return math.log(n) / math.log(2)
end

-- 故障分析
function GetFaultAnaly(strRes, explain) -- 所有字节字符串 | explain结果table
    local strExplain = ""
    for k = #strRes, 1, -1 do
        local str1k_end = string.sub(strRes, k, #strRes)
        local num1k_end = math.modf(lg2(tonumber(str1k_end, 16)))
        if (num1k_end >= 4 * (#strRes - k)) then
            strExplain = strExplain .. explain[num1k_end + 1] .. " "
        end
    end
    return strExplain
end

-- 获取指定起始位的索引
function GetStartByte(startIndex, count, tabBuf)
    for i = startIndex, count do
        if (tonumber(tabBuf[i]) == 0x68) then
            startIndex = i
            break
        end
    end
    return startIndex
end

function AnalysisRx(sAddr, rxBufCnt)
    local mFunCode = 0
    local mRegByte = 0
    local crcTemp

    local VariableMap = {
        Status = "1",
        Variable = {}
    }

    -- 回应帧最短为13个字节(异常) 起始位(1)+--地址域A0-A5(6)+起始位(1)+异常控制码(1)+数据域长度(1)+错误信息字ERR(1)                    +校验码(1)+停止位(1)
    -- 回应帧最短为17个字节(正常) 起始位(1)+--地址域A0-A5(6)+起始位(1)+正常控制码(1)+数据域长度(1)+标识码(4)+数据(>=1,写数据-上电合闸状态)+校验码(1)+停止位(1)
    if (rxBufCnt < 13) then -- 字节不足
        rxBuf = {}
        VariableMap = {
            Status = "1",
            Variable = {}
        }
        return VariableMap
    end

    for index = 1, rxBufCnt do
        if ((index + 12) <= rxBufCnt) then -- 因为index是从1开始的，所以是+4
            local startIndex = 0
            startIndex = GetStartByte(startIndex, rxBufCnt, rxBuf) -- 5
            if (startIndex == nil or startIndex <= 0) then
                Luaprint("startIndex Error! -- Non Positive Number or nil")
                rxBuf = {}
                return VariableMap
            end
            local mAddr = AnalysisRxData(rxBuf, { 6 }, startIndex + 1, false) -- 通信地址
            if (mAddr[1] == sAddr) then
                mFunCode = rxBuf[startIndex + 8] -- 控制码
                if (mFunCode == 0x91) then
                    mRegByte = rxBuf[startIndex + 9] -- 数据域长度
                    local byteLength = startIndex + 9 + mRegByte + 2 -- 有效字节数
                    if (byteLength > #rxBuf) then -- 有效字节数判断
                        Luaprint(string.format("Error! --  Out Of Range: byteLength: %s > #rxBuf: %s", byteLength,
                            #rxBuf))
                        rxBuf = {}
                        return VariableMap
                    end
                    -- 暂存数据域数据
                    local temp = {}
                    for i = startIndex, byteLength - 2 do
                        if rxBuf[i] ~= nil then
                            table.insert(temp, rxBuf[i])
                        end
                    end
                    local crc = GetCRC(temp, 1)
                    crcTemp = rxBuf[byteLength - 1]
                    if (crc == crcTemp) then
                        local Variable = {}
                        local VariableIndex = 1
                        if (regAddr == 0x0000) then
                            local identifyCodes = { 4 } -- 标识码
                            startIndex = GetStartByte(startIndex + 1, rxBufCnt, rxBuf)
                            local strRes = AnalysisRxData(rxBuf, identifyCodes, startIndex + 3, true)

                            if (strRes[1] == "04FF0501") then -- 故障分析
                                local faultAnalysis = { 4, 4, 1, 2, 4, 4 }
                                local explain = {}
                                local strExplain = ""
                                strRes, tabRes = AnalysisRxData(rxBuf, faultAnalysis, startIndex + 7, true)
                                ---------解析断电故障/开关状态数据并加入上报的map中-----------------
                                local FaultAnaly = strRes[1]
                                Luaprint("FaultAnaly = " .. FaultAnaly)
                                explain = { "过压拉闸:故障", "欠压拉闸:故障",
                                    "延时过流(过载)拉闸:故障", "用电量超额拉闸:故障",
                                    "定时拉闸", "远程拉闸", "超规定自动合闸次数:故障",
                                    "快速电流拉闸:故障", "手动合闸", "手动拉闸", "远程合闸",
                                    "漏电拉闸:故障", "过温拉闸:故障", "漏电自检拉闸",
                                    "上级保护合闸", "上级保护拉闸", "定时合闸",
                                    "漏电自检失败:故障", "开关故障:故障", "过压恢复合闸",
                                    "欠压恢复合闸", "上电合闸", "上电拉闸", "电弧拉闸",
                                    "漏电自检恢复合闸" }
                                strExplain = tonumber(FaultAnaly) == 0 and "无" or GetFaultAnaly(FaultAnaly, explain)
                                Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "FaultAnaly",
                                    tonumber(FaultAnaly), "断电故障/开关状态: " .. strExplain)
                                VariableIndex = VariableIndex + 1
                                ---------解析事件分析数据并加入上报的map中-----------------
                                local EventAnaly = strRes[2]
                                Luaprint("EventAnaly = " .. EventAnaly)
                                explain = { "过压", "欠压", "过流", "快速过流", "过温", "漏电",
                                    "电量超额", "电量超额提示", "过压恢复", "欠压恢复",
                                    "漏电自检拉闸", "漏电自检合闸", "定时合闸", "定时拉闸",
                                    "命令合闸", "命令拉闸", "上电合闸", "上电拉闸" }
                                strExplain = tonumber(EventAnaly) == 0 and "无" or GetFaultAnaly(EventAnaly, explain)
                                Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "EventAnaly",
                                    tonumber(EventAnaly), strExplain)
                                VariableIndex = VariableIndex + 1
                                ---------解析开关状态数据并加入上报的map中-----------------
                                local OnOffAnaly = strRes[3]
                                Luaprint("OnOffAnaly = " .. OnOffAnaly)
                                explain = { "合闸", "拉闸", "未知", "故障" }
                                strExplain = "开关状态: " .. explain[tonumber(string.sub(OnOffAnaly, 2)) + 1] ..
                                    "、上级开关状态: " ..
                                    (tonumber(string.sub(OnOffAnaly, 1, 1)) == 0 and "合闸" or "拉闸")
                                Luaprint("OnOffAnaly = " .. OnOffAnaly .. ", strExplain = " .. strExplain)
                                Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "OnOffAnaly",
                                    tonumber(OnOffAnaly), strExplain)
                                VariableIndex = VariableIndex + 1
                                ---------解析操作流水号数据并加入上报的map中-----------------
                                local SerialNumber = strRes[4]
                                SerialNumber = "0x"..SerialNumber
                                Luaprint("SerialNumber = " .. SerialNumber)
                                strExplain = tonumber(SerialNumber) == 0 and "无" or "开关状态改变的次数: " ..
                                    tonumber(SerialNumber)
                                Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "SerialNumber",
                                    tonumber(SerialNumber), strExplain)
                                VariableIndex = VariableIndex + 1
                                ---------解析开关动作对应的当前采集值数据并加入上报的map中-----------------
                                local CurrentValue = strRes[5]
                                Luaprint("CurrentValue = " .. CurrentValue)
                                strExplain = tonumber(CurrentValue) == 0 and "无" or CurrentValue
                                Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "CurrentValue",
                                    tonumber(CurrentValue), strExplain)
                                VariableIndex = VariableIndex + 1
                                ---------解析开关动作对应的阈值分析数据并加入上报的map中-----------------
                                local Threshold = strRes[6]
                                Luaprint("Threshold = " .. Threshold)
                                strExplain = tonumber(Threshold) == 0 and "无" or Threshold
                                Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "Threshold",
                                    tonumber(Threshold), strExplain)
                                ----------------------------------------------------
                                VariableMap = {
                                    Status = "0",
                                    Variable = Variable
                                }
                                rxBuf = {}
                                return VariableMap
                            elseif (strRes[1] ~= "04FF0802") then
                                rxBuf = {}
                                return VariableMap
                            end
                            local elecQuantity = { 4, 4, 4, 4, 2, 3, 3, 3, 2, 2, 4, 3, 2, 2, 1, 1 }
                            strRes = AnalysisRxData(rxBuf, elecQuantity, startIndex + 7, true)
                            ---------解析有功电量数据并加入上报的map中-------------
                            local Ep = strRes[1]
                            Ep = tonumber(Ep)
                            Luaprint("Ep = " .. Ep .. ": " .. Ep / 100)
                            Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "TotalEnergy", Ep, "有功电量")
                            VariableIndex = VariableIndex + 1
                            ---------解析月度有功电量数据并加入上报的map中-------------
                            local MonthlyEp = strRes[2]
                            MonthlyEp = tonumber(MonthlyEp)
                            Luaprint("MonthlyEp = " .. MonthlyEp .. ": " .. MonthlyEp / 100)
                            Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "MonthlyEp", MonthlyEp,
                                "月度有功电量")
                            VariableIndex = VariableIndex + 1
                            ---------解析无功电量数据并加入上报的map中-------------
                            local Eq = strRes[3]
                            Eq = tonumber(Eq)
                            Luaprint("Eq = " .. Eq .. ": " .. Eq / 100)
                            Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "Eq", Eq, "无功电量")
                            VariableIndex = VariableIndex + 1
                            ---------解析月度无功电量数据并加入上报的map中---------------
                            local MonthlyEq = strRes[4]
                            MonthlyEq = tonumber(MonthlyEq)
                            Luaprint("MonthlyEq = " .. MonthlyEq .. ": " .. MonthlyEq / 100)
                            Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "MonthlyEq", MonthlyEq,
                                "月度无功电量")
                            VariableIndex = VariableIndex + 1
                            ---------解析电压数据并加入上报的map中---------------
                            local U = strRes[5]
                            U = tonumber(U)
                            Luaprint("U = " .. U .. ": " .. U / 10)
                            Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "U", U, "电压")
                            VariableIndex = VariableIndex + 1
                            ---------解析电流数据并加入上报的map中---------------
                            local I = strRes[6]
                            I = tonumber(I)
                            Luaprint("I = " .. I .. ": " .. I / 1000)
                            Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "I", I, "电流")
                            VariableIndex = VariableIndex + 1
                            ---------解析有功功率数据并加入上报的map中---------------
                            local P = strRes[7]
                            P = tonumber(P)
                            Luaprint("P = " .. P .. ": " .. P / 10000)
                            Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "P", P, "有功功率")
                            VariableIndex = VariableIndex + 1
                            ---------解析无功功率数据并加入上报的map中---------------
                            local Q = strRes[8]
                            Q = tonumber(Q)
                            Luaprint("Q = " .. Q .. ": " .. tonumber(Q) / 10000)
                            Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "Q", Q, "无功功率")
                            VariableIndex = VariableIndex + 1
                            ---------解析功率因数数据并加入上报的map中-----------------
                            local PF = strRes[9]
                            PF = tonumber(PF)
                            Luaprint("PF = " .. PF .. ": " .. PF / 1000)
                            Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "PF", PF, "功率因数")
                            VariableIndex = VariableIndex + 1
                            ---------解析频率数据并加入上报的map中-----------------
                            local FR = strRes[10]
                            FR = tonumber(FR)
                            Luaprint("FR = " .. FR .. ": " .. FR / 100)
                            Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "FR", FR, "频率")
                            VariableIndex = VariableIndex + 1
                            ---------解析日期时间数据为unix时间戳并加入上报的map中-----------------
                            local UnixStampDate = strRes[11]
                            Luaprint("UnixStampDate = " .. UnixStampDate)
                            local UnixStampTime = strRes[12]
                            Luaprint("UnixStampTime = " .. UnixStampTime)

                            local unixTimeStamp = os.time({
                                year = 2000 + tonumber(string.sub(UnixStampDate, 1, 2)),
                                month = tonumber(string.sub(UnixStampDate, 3, 4)),
                                day = tonumber(string.sub(UnixStampDate, 5, 6)),
                                hour = tonumber(string.sub(UnixStampTime, 1, 2)),
                                min = tonumber(string.sub(UnixStampTime, 3, 4)),
                                sec = tonumber(string.sub(UnixStampTime, 5, 6))
                            })
                            Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "UnixTimeStamp",
                                unixTimeStamp, "unix时间戳")
                            VariableIndex = VariableIndex + 1
                            ---------解析温度数据并加入上报的map中-----------------
                            local Temperature = strRes[13]
                            Temperature = tonumber(Temperature)
                            Luaprint("Temperature = " .. Temperature .. ": " .. Temperature / 10)
                            Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "Temperature", Temperature,
                                "温度")
                            VariableIndex = VariableIndex + 1
                            ---------解析漏电流数据并加入上报的map中-----------------
                            local Leakage = strRes[14]
                            Leakage = tonumber(Leakage)
                            Luaprint("Leakage = " .. Leakage)
                            Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "Leakage", Leakage, "频率")
                            VariableIndex = VariableIndex + 1
                            ---------解析开关状态数据并加入上报的map中-----------------
                            local Status = strRes[15]
                            Status = tonumber(Status)
                            Status = 1 - Status --协议里继电器状态0为合闸1为拉闸，为了与读取统一，01互换
                            Luaprint("Status = " .. Status)
                            local explain = { "拉闸", "合闸", "未知", "开关故障" }
                            print("Status = " .. Status .. ", strExplain = " .. "状态: " .. explain[Status + 1])
                            Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "StartStopStatus", Status,
                                "状态: " .. explain[Status + 1])
                            VariableIndex = VariableIndex + 1
                            ---------解析相位角数据并加入上报的map中-----------------
                            local phaseAngle = strRes[16]
                            phaseAngle = tonumber(phaseAngle)
                            Luaprint("phaseAngle= " .. phaseAngle)
                            Variable[VariableIndex] = utils.AppendVariable(VariableIndex, "PhaseAngle", phaseAngle,
                                "相位角")
                            VariableIndex = VariableIndex + 1
                            ----------------------------------------------------
                            VariableMap = {
                                Status = "0",
                                Variable = Variable
                            }
                        end
                        rxBuf = {}
                        return VariableMap
                    end
                elseif (mFunCode == 0x9C) then
                    -- startIndex = GetStartByte(startIndex + 1, rxBufCnt, rxBuf)
                    local errorCode = AnalysisRxData(rxBuf, { 1 }, startIndex + 9, false)
                    -- print("#errorCode:" .. #errorCode .. ", errorCode[1]:" .. errorCode[1])
                    if (tonumber(errorCode[1]) == 0) then
                        print("0")
                        VariableMap = {
                            Status = "0",
                            Variable = {}
                        }
                    end
                elseif (mFunCode == 0xDC) then
                    -- startIndex = GetStartByte(startIndex + 1, rxBufCnt, rxBuf)
                    local errorCode = AnalysisRxData(rxBuf, { 1 }, startIndex + 9, false)
                    if (tonumber(errorCode[1]) == 1) then
                        VariableMap = {
                            Status = "1",
                            Variable = {}
                        }
                    end
                end
            end
        end
    end
    rxBuf = {}
    return VariableMap
end

-- 测试环境下调试发送指令
if (TestEnv() == true) then --
    GenerateGetRealVariables(202109018002, 1)
    -- DeviceCustomCmd(202109018002, "SetVariables", 0, 0)
    AnalysisRx("202109018002", 16)
end